using System;

using Weazel.Gezel.Model;
using Weazel.Gezel.Parser;
using Weazel.Gezel.Simulator.Reference;
using Weazel.Gezel.Simulator.Reference.Setup;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using GezelModel = Weazel.Gezel.Model.Model;


namespace Weazel.Gezel.Simulator.Reference.Test
{
  [TestClass]
  public class TestRuntimeErrors
  {
    [TestMethod]
    public void TestCombinatorialLoop()
    {
      const string description = @"
        dp mydp (out a: ns(8)){
	        sig b, c : ns(8);
	        sfg exec {
		        a = b;
		        b = c;
		        c = a; // ooops, combinatorial loop
	        }
        }

        hardwired hw(mydp) { exec; }

        system T {
	        mydp;
        }";

      GezelModel model = ParseModel.ParseAndVerify(description);
      Assert.IsTrue(model.IsVerified);



      Simulation simulation = new Simulation();
      SimulationSetup.SetupFromModel(simulation, model);

			//System.Windows.Forms.MessageBox.Show(Weazel.Gezel.Exporter.ModelExporter.ToGezelString(model));
			

      SimulationResult result = simulation.Run(1);

      Assert.IsTrue(result.Exception != null);
      Assert.AreEqual(result.Exception.GetType(), typeof(CombinatorialLoopException));
    }

    [TestMethod]
    public void TestRomMissingFile()
    {
      string description = @"
        ipblock test_rom(
          in address: ns(8);           
          in rd: ns(1);                
          out odata: ns(32)            
        ){
          iptype " + "\"rom\";" + @" 
          ipparm " + "\"size=10\";" + @" 
          ipparm " + "\"wl=8\";" + @"   
          ipparm " + "\"startbyte=1\";" + @" // fatal error if 0!
          ipparm " + "\"file = nonexistent.bin\";" + @" 
        };
  
        system T {
          test_rom(a, b, c);
        }  
        ";

      GezelModel model = ParseModel.ParseAndVerify(description);
      Assert.IsTrue(model.IsVerified);

      Simulation simulation = new Simulation();

      SimulationResult result = simulation.SetupAndRun(model, 1);

      Assert.IsTrue(result.Exception is IpBlockFileNotFoundException);
      Assert.AreEqual(new System.IO.FileInfo((result.Exception as IpBlockFileNotFoundException).Filename).Name, "nonexistent.bin");
    }

    [TestMethod]
    public void TestUnknownIpType()
    {
      const string description =@"
        ipblock mic1_rom(
          in address: ns(8);           
          in rd: ns(1);                
          out odata: ns(32)            
        ){
          iptype " + "\"heste\";" + @"
        }

        system T {
	        mic1_rom;
        }
      ";

      GezelModel model = ParseModel.ParseAndVerify(description);
      Assert.IsTrue(model.IsVerified);

      Simulation simulation = new Simulation();
      SimulationResult result = simulation.SetupAndRun(model, 1);

      Assert.IsTrue(result.Exception != null);
      Assert.IsTrue(result.Exception is UnknownIpBlockException);
    }
  }
}
